# pylint: disable=invalid-name,line-too-long

import pytest

from allennlp.data.dataset_readers.semantic_parsing.grammar_based_text2sql import (
    GrammarBasedText2SqlDatasetReader,
)
from allennlp.common.testing import AllenNlpTestCase


@pytest.mark.skip(reason="Mark will fix in a nearby PR.")
class TestGrammarBasedText2SqlDatasetReader(AllenNlpTestCase):
    def setUp(self):
        super().setUp()
        self.data_path = str(self.FIXTURES_ROOT / "data" / "text2sql" / "*.json")
        self.schema = str(
            self.FIXTURES_ROOT / "data" / "text2sql" / "restaurants-schema.csv"
        )
        self.database = str(self.FIXTURES_ROOT / "data" / "text2sql" / "restaurants.db")

        self.reader = GrammarBasedText2SqlDatasetReader(self.schema, self.database)

    def test_reader_can_read_data_with_entity_pre_linking(self):
        instances = self.reader.read(self.data_path)
        instances = list(instances)
        assert len(instances) == 5

        fields = instances[0].fields
        token_field = fields["tokens"]
        tokens = [t.text for t in token_field.tokens]
        assert tokens == [
            "how",
            "many",
            "buttercup",
            "kitchen",
            "are",
            "there",
            "in",
            "san",
            "francisco",
            "?",
        ]

        action_sequence = fields["action_sequence"].field_list
        indices = [x.sequence_index for x in action_sequence]

        assert indices == [
            93,
            75,
            78,
            88,
            86,
            82,
            39,
            113,
            48,
            42,
            2,
            46,
            91,
            90,
            102,
            92,
            90,
            103,
            118,
            34,
            5,
            112,
            21,
            102,
            23,
            13,
            34,
            5,
            116,
            95,
            16,
            34,
            5,
            112,
            21,
            103,
            30,
            13,
            34,
            5,
            112,
            21,
            102,
            30,
            16,
            34,
            5,
            112,
            21,
            103,
            27,
            13,
            39,
            116,
            96,
        ]

        action_fields = fields["valid_actions"].field_list
        production_rules = [(x.rule, x.is_global_rule) for x in action_fields]

        assert production_rules == [
            ('arg_list -> [expr, ",", arg_list]', True),
            ("arg_list -> [expr]", True),
            ('arg_list_or_star -> ["*"]', True),
            ("arg_list_or_star -> [arg_list]", True),
            ('between_expr -> [value, "BETWEEN", value, "AND", value]', True),
            ("binary_expr -> [value, binaryop, expr]", True),
            ('binaryop -> ["*"]', True),
            ('binaryop -> ["+"]', True),
            ('binaryop -> ["-"]', True),
            ('binaryop -> ["/"]', True),
            ('binaryop -> ["<"]', True),
            ('binaryop -> ["<="]', True),
            ('binaryop -> ["<>"]', True),
            ('binaryop -> ["="]', True),
            ('binaryop -> [">"]', True),
            ('binaryop -> [">="]', True),
            ('binaryop -> ["AND"]', True),
            ('binaryop -> ["LIKE"]', True),
            ('binaryop -> ["OR"]', True),
            ('boolean -> ["false"]', True),
            ('boolean -> ["true"]', True),
            ('col_ref -> [table_name, ".", column_name]', True),
            ("col_ref -> [table_name]", True),
            ('column_name -> ["CITY_NAME"]', True),
            ('column_name -> ["COUNTY"]', True),
            ('column_name -> ["FOOD_TYPE"]', True),
            ('column_name -> ["HOUSE_NUMBER"]', True),
            ('column_name -> ["NAME"]', True),
            ('column_name -> ["RATING"]', True),
            ('column_name -> ["REGION"]', True),
            ('column_name -> ["RESTAURANT_ID"]', True),
            ('column_name -> ["STREET_NAME"]', True),
            ('expr -> ["(", query, ")"]', True),
            ("expr -> [between_expr]", True),
            ("expr -> [binary_expr]", True),
            ("expr -> [in_expr]", True),
            ("expr -> [like_expr]", True),
            ("expr -> [null_check_expr]", True),
            ("expr -> [unary_expr]", True),
            ("expr -> [value]", True),
            ('fname -> ["ALL"]', True),
            ('fname -> ["AVG"]', True),
            ('fname -> ["COUNT"]', True),
            ('fname -> ["MAX"]', True),
            ('fname -> ["MIN"]', True),
            ('fname -> ["SUM"]', True),
            ('from_clause -> ["FROM", source]', True),
            ('function -> [fname, "(", "DISTINCT", arg_list_or_star, ")"]', True),
            ('function -> [fname, "(", arg_list_or_star, ")"]', True),
            ('group_clause -> [expr, "," group_clause]', True),
            ("group_clause -> [expr]", True),
            ('groupby_clause -> ["GROUP", "BY" group_clause, "HAVING", expr]', True),
            ('groupby_clause -> ["GROUP", "BY" group_clause]', True),
            ('in_expr -> [value, "IN", expr]', True),
            ('in_expr -> [value, "IN", string_set]', True),
            ('in_expr -> [value, "NOT", "IN", expr]', True),
            ('in_expr -> [value, "NOT", "IN", string_set]', True),
            ('like_expr -> [value, "LIKE", string]', True),
            ('limit -> ["LIMIT", number]', True),
            ('null_check_expr -> [col_ref, "IS", "NOT", "NULL"]', True),
            ('null_check_expr -> [col_ref, "IS", "NULL"]', True),
            ('order_clause -> [ordering_term, "," order_clause]', True),
            ("order_clause -> [ordering_term]", True),
            ('orderby_clause -> ["ORDER", "BY" order_clause]', True),
            ('ordering -> ["ASC"]', True),
            ('ordering -> ["DESC"]', True),
            ("ordering_term -> [expr ordering]", True),
            ("ordering_term -> [expr]", True),
            ('parenval -> ["(", expr, ")"]', True),
            ("query -> [select_core groupby_clause, limit]", True),
            ("query -> [select_core groupby_clause, orderby_clause, limit]", True),
            ("query -> [select_core groupby_clause, orderby_clause]", True),
            ("query -> [select_core groupby_clause]", True),
            ("query -> [select_core orderby_clause, limit]", True),
            ("query -> [select_core orderby_clause]", True),
            ("query -> [select_core]", True),
            ("sel_res_all_star -> ['*']", True),
            ('sel_res_tab_star -> [table_name ".*"]', True),
            (
                "select_core -> [select_with_distinct select_results from_clause where_clause]",
                True,
            ),
            ("select_core -> [select_with_distinct select_results from_clause]", True),
            ("select_core -> [select_with_distinct select_results where_clause]", True),
            ("select_core -> [select_with_distinct select_results]", True),
            ("select_result -> [expr]", True),
            ("select_result -> [sel_res_all_star]", True),
            ("select_result -> [sel_res_tab_star]", True),
            ('select_results -> [select_result, ",", select_results]', True),
            ("select_results -> [select_result]", True),
            ('select_with_distinct -> ["SELECT", "DISTINCT"]', True),
            ('select_with_distinct -> ["SELECT"]', True),
            ('single_source -> ["(", query, ")"]', True),
            ("single_source -> [table_name]", True),
            ('source -> [single_source, ",", source]', True),
            ("source -> [single_source]", True),
            ('statement -> [query, ";"]', True),
            ("statement -> [query]", True),
            ("string -> [\"'city_name0'\"]", True),
            ("string -> [\"'name0'\"]", True),
            ("string -> [~\"'.*?'\"iu]", True),
            ('string_set -> ["(", string_set_vals, ")"]', True),
            ('string_set_vals -> [string, ",", string_set_vals]', True),
            ("string_set_vals -> [string]", True),
            ('table_name -> ["GEOGRAPHIC"]', True),
            ('table_name -> ["LOCATION"]', True),
            ('table_name -> ["RESTAURANT"]', True),
            ("unary_expr -> [unaryop expr]", True),
            ('unaryop -> ["+"]', True),
            ('unaryop -> ["-"]', True),
            ('unaryop -> ["NOT"]', True),
            ('unaryop -> ["not"]', True),
            ('value -> ["2.5"]', True),
            ('value -> ["YEAR(CURDATE())"]', True),
            ("value -> [boolean]", True),
            ("value -> [col_ref]", True),
            ("value -> [function]", True),
            ("value -> [number]", True),
            ("value -> [parenval]", True),
            ("value -> [string]", True),
            ('where_clause -> ["WHERE", expr where_conj]', True),
            ('where_clause -> ["WHERE", expr]', True),
            ('where_conj -> ["AND", expr where_conj]', True),
            ('where_conj -> ["AND", expr]', True),
        ]
